package com.cxyd.modules.wcs.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cxyd.common.constant.RcsConstants;
import com.cxyd.common.constant.WcsConstants;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.common.utils.ConvertUtils;
import com.cxyd.modules.api.dto.RcsResultHK;
import com.cxyd.modules.log.service.SysLogWorkService;
import com.cxyd.modules.wcs.dao.AgvCallbackHkDao;
import com.cxyd.modules.wcs.dto.AgvCallbackHkDTO;
import com.cxyd.modules.wcs.entity.*;
import com.cxyd.modules.wcs.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

@Service
public class AgvCallbackHkServiceImpl extends CrudServiceImpl<AgvCallbackHkDao, AgvCallbackHkEntity, AgvCallbackHkDTO> implements AgvCallbackHkService {
    @Resource
    private AgvTrkHkService hkService;
    @Resource
    private TrkService trkService;
    @Resource
    private PostWmsService postWmsService;
    @Resource
    private PcItemService pcItemService;
    @Resource
    private SysLogWorkService logWorkService;

    @Override
    public QueryWrapper<AgvCallbackHkEntity> getWrapper(Map<String, Object> params) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RcsResultHK callbackHandle(AgvCallbackHkDTO dto) {
        String workName = "[流程-4]执行通知-HK";
        String workProc = "AgvCallbackHkServiceImpl.callbackHandle";
//        1.对json报文进行解析(获取reqCode,taskCode,robotCode,method,currentPositionCode)
        String reqCode = dto.getReqCode();
        String taskCode = dto.getTaskCode();
        String robotCode = dto.getRobotCode();
//        method为重要字段(start/oubin/get/put/end等)
        String method = dto.getMethod();
//        当前站点信息(货位站点)
        String positionCode = dto.getStgBinCode();
//        根据taskCode获取任务信息
        AgvTrkHkEntity task = hkService.getAgvTrkByTaskCode(taskCode);
        if (task == null) {
            String pCode = "callbackHandle_001";
            String pMsg = "任务单[" + taskCode + "]无执行任务!reqCode[" + reqCode + "]";
            logWorkService.workLogging(workName, taskCode, pCode,
                    pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
            return new RcsResultHK().error(reqCode, pMsg);
        }
//        记录车号
        task.setAgvCode(robotCode);
//        不同的method调用不同的处理逻辑
        if (RcsConstants.HK_METHOD_START.equals(method)) {
//       1.任务开始(start)-只接收并处理一次
            if (task.getStatus() == RcsConstants.HK_STATUS_POST) {
                agvTrkStart(task, positionCode);
            }
        } else if (RcsConstants.HK_METHOD_OUTBIN.equals(method)) {
//      2.走出储位(可认为是下架)
            agvTrkOutbin(task, positionCode);
        } else if (RcsConstants.HK_METHOD_GET.equals(method)) {
//      4.CTU料箱取申请(可能需要任务继续)
            agvTrkApplyGet(task, positionCode);
//      将callback记录更新为需任务继续(status=1)
        } else if (RcsConstants.HK_METHOD_GET_DONE.equals(method)) {
            agvTrkApplyGetDone(task, positionCode);
        } else if (RcsConstants.HK_METHOD_PUT.equals(method)) {
//      5.CTU料箱放申请(可能需要任务继续)
            agvTrkApplyPut(task, positionCode);
        } else if (RcsConstants.HK_METHOD_PUT_DONE.equals(method)) {

        } else if (RcsConstants.HK_METHOD_END.equals(method)) {
//      3.任务结束
            agvTrkEnd(task, positionCode);
        } else {

        }
        return new RcsResultHK().success(reqCode);
    }

    /***
     * 任务开始
     * @param task
     */
    private void agvTrkStart(AgvTrkHkEntity task, String positionCode) {
        String workName = "[流程-4]任务开始-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkStart";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "小车[" + task.getAgvCode() + "]准备从站点[" + positionCode + "]搬送料箱[" + task.getCtnrCode() + "]!method为[start]";
//        start时并未执行该任务,只是说CTU接到有任务而已
        task.setStatus(RcsConstants.HK_STATUS_START);
        task.setCurrentPositionCode(positionCode);
        task.setData("RCS接收任务后开始执行!method-[start]");
        task.setUpdater(WcsConstants.WCS_USER_ID);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
//        找到对应[wcs_trk]任务进行更新
        TrkEntity trkEntity = trkService.selectById(task.getTrkId());
        if (trkEntity == null) {
            return;
        }
        trkEntity.setComments(pMsg);
        trkEntity.setUpdater(WcsConstants.WCS_USER_ID);
        trkEntity.setUpdateDate(new Date());
        trkService.updateById(trkEntity);
//        以料箱维度记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }

    /***
     * 走出储位（一般为出库下架）
     * @param task
     */
    private void agvTrkOutbin(AgvTrkHkEntity task, String positionCode) {
//        通知wms料箱已下架等
        String workName = "[流程-DOWN]料箱下架-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkOutbin";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "小车[" + task.getAgvCode() + "]搬送料箱[" + task.getCtnrCode() + "]从[" + positionCode + "]走出储位!method为[outbin]";
        task.setStatus(RcsConstants.HK_STATUS_TAKE);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
        TrkEntity trkEntity = trkService.selectById(task.getTrkId());
//      任务接收后上报wms系统[wcs_post_wms]
        PostWmsEntity postWms = new PostWmsEntity();
        postWms.setRequestPk(trkEntity.getRequestPk());
        postWms.setContNo(trkEntity.getContNo());
        postWms.setCurPos(trkEntity.getToPos());
//        类型为[1-通知]
        postWms.setNoticeType(WcsConstants.POST_TYPE_NOTICE);
        postWms.setCode(pCode);
        postWms.setResult(pMsg);
        postWms.setPostSt(WcsConstants.POST_STATUS_START);
        postWms.setCreator(WcsConstants.WCS_USER_ID);
        postWms.setUpdateDate(new Date());
//        更新wcs_trk任务为执行中
        trkEntity.setComments(pMsg);
        trkEntity.setUpdateDate(new Date());
        trkService.updateById(trkEntity);
        postWmsService.insert(postWms);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }

    /***
     * CTU取放申请
     * @param task
     */
    private void agvTrkApplyGet(AgvTrkHkEntity task, String positionCode) {
        String workName = "[流程-GET]取货-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkApplyGet";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "[" + task.getAgvCode() + "]号车在[" + positionCode + "]申请取料箱[" + task.getCtnrCode() + "]!";
//        取放时通知线体取料申请信号
        pcItemService.updateSingleByNo("PC_GET_APPLY_01", "True");
        task.setStatus(RcsConstants.HK_STATUS_GET);//作业申请
        task.setTokenCode(IdUtil.simpleUUID());
        task.setPositionCode(positionCode);
        task.setData(pMsg);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }

    /***
     * CTU取完成
     * @param task
     */
    private void agvTrkApplyGetDone(AgvTrkHkEntity task, String positionCode) {
        String workName = "[流程-GET-DONE]-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkApplyGetDone";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "[" + task.getAgvCode() + "]号车在[" + positionCode + "]取料箱[" + task.getCtnrCode() + "]完成!";
//        取放时通知线体取料完成信号
        pcItemService.updateSingleByNo("PC_GET_LEAVE_01", "True");
        task.setStatus(RcsConstants.HK_STATUS_GET_DONE);//作业申请
        task.setData(pMsg);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }

    private void agvTrkApplyPut(AgvTrkHkEntity task, String positionCode) {
        String workName = "[流程-PUT]放货-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkApplyPut";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "[" + task.getAgvCode() + "]号小车在[" + positionCode + "]申请放料箱";
//        取放时通知线体完成信号
        pcItemService.updateSingleByNo("PC_PUT_APPLY_02", "True");
        task.setStatus(RcsConstants.HK_STATUS_PUT);//作业申请
        task.setTokenCode(IdUtil.simpleUUID());
        task.setPositionCode(positionCode);
        task.setData(pMsg);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }

    /***
     * 任务结束(将对应agv搬送任务完成并转移历史)
     * @param task
     */
    private void agvTrkEnd(AgvTrkHkEntity task, String positionCode) {
        String workName = "[流程-5]任务结束-HK";
        String workProc = "AgvCallbackHkServiceImpl.agvTrkEnd";
        String pCode = WcsConstants.PROC_CODE_SUCCESS;
        String pMsg = "小车[" + task.getAgvCode() + "]搬送料箱[" + task.getCtnrCode() + "]到达站点[" + positionCode + "]!method为[end]";
//      获取[wcs_trk]信息
        task.setStatus(RcsConstants.HK_STATUS_END); //任务完成
        task.setCurrentPositionCode(positionCode);
        task.setUpdateDate(new Date());
        hkService.updateById(task);
        TrkEntity trkEntity = trkService.selectById(task.getTrkId());
        if (trkEntity == null) {
            return;
        }
        trkEntity.setTrkSt(WcsConstants.TRK_STATUS_DONE);
        trkEntity.setComments(pMsg);
        trkEntity.setCurPos(positionCode);
        trkEntity.setUpdater(WcsConstants.WCS_USER_ID);
        trkEntity.setUpdateDate(new Date());
        trkService.updateById(trkEntity);
//      任务接收后上报wms系统[wcs_post_wms]
        PostWmsEntity postWms = new PostWmsEntity();
        postWms.setRequestPk(trkEntity.getRequestPk());
        postWms.setContNo(trkEntity.getContNo());
        postWms.setCurPos(trkEntity.getToPos());
//        类型为[完成]
        postWms.setNoticeType(WcsConstants.POST_TYPE_DONE);
        postWms.setCode(pCode);
        postWms.setResult(pMsg);
        postWms.setPostSt(WcsConstants.POST_STATUS_START);
        postWms.setCreator(WcsConstants.WCS_USER_ID);
        postWms.setUpdateDate(new Date());
        postWmsService.insert(postWms);
        //如果任务类型是OT,还需要告知线体放货离开
        if (WcsConstants.TRK_TYPE_OT.equals(trkEntity.getTrkType())) {
            pcItemService.updateSingleByNo("PC_PUT_LEAVE_02", "True");
        }
        //数据处理完毕后将agv_trk_hk的任务做转移(此处不再转移,当任务上报完成后再转移)
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, WcsConstants.WCS_USER_NAME, 10L);
    }
}
